﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
using HP.Cachalote.Services;
using HP.Cachalote.Services.Interfaces;
using HP.Cachalote.Repositories.Interfaces;
using HP.Cachalote.UnitTests.FakeRepositories;
using HP.Cachalote.DataModels;

namespace HP.Cachalote.UnitTests.ServiceTests
{
    [TestFixture]
    public class LabelServiceTests
    {
        private IRepositoryFactory _repositoryFactory;
        private IServiceFactory _serviceFactory;
        private ITodoLabelService _labelService;

        [SetUp]
        protected void Setup()
        {
            _repositoryFactory = new FakeRepositoryFactory();
            _serviceFactory = new ServiceFactory(_repositoryFactory);
            _labelService = _serviceFactory.CreateLabelService();
        }

        [Test]
        public void GetAllTest()
        {
            var expected = 5;
            var actual = _labelService.GetAll().Count;

            Assert.AreEqual(expected, actual, "The count of GetAll should be 5.");
        }

        [Test]
        public void AddTest()
        {
            var oldCount = _labelService.Filter(o => o.Parent == null).Count;
            var maxIndex = _labelService.Filter(o => o.Parent == null).Max(o => o.OrderIndex);

            TodoLabel label = new TodoLabel
            {
                ID = 6,
                Name = "New TodoLable",
                Icon = null,
                Parent = null,
                SubLabels = new List<TodoLabel>(),
                OrderIndex = maxIndex + 1,
                TodoItems = new List<TodoItem>()
            };

            Assert.AreEqual(null, _labelService.Get(label.ID));

            _labelService.Add(label);

            Assert.AreEqual(label.Name, _labelService.Get(label.ID).Name);
            Assert.AreEqual(oldCount + 1, _labelService.Filter(o => o.Parent == null).Count);
        }

        [Test]
        public void AddOrUpdateTest()
        {
            int labelID = 2;
            TodoLabel label = _labelService.Get(labelID);
            int oldCount = _labelService.GetAll().Count;

            string newName = "New LableName";
            Assert.AreNotEqual(null, label);
            Assert.AreNotEqual(newName, label.Name);

            label.Name = newName;

            _labelService.AddOrUpdate(label);
            int newCount = _labelService.GetAll().Count;

            Assert.AreEqual(newName, label.Name);
            Assert.AreEqual(oldCount, newCount);
        }


        [Test]
        public void DeleteTest()
        {
            var OldCount = _labelService.Filter(o => o.Parent == null).Count;
            var OldOrderIndex = _labelService.Filter(o => o.Parent == null).Max(o => o.OrderIndex);

            var actual = _labelService.Filter(o => o.Parent == null).Where(o => o.OrderIndex == OldOrderIndex).FirstOrDefault();

            Assert.AreNotEqual(null, actual);

            _labelService.Delete(actual);

            var newCount = _labelService.Filter(o => o.Parent == null).Count;
            var newOrderIndex = _labelService.Filter(o => o.Parent == null).Max(o => o.OrderIndex);

            Assert.AreEqual(newCount, (OldCount - 1), "Delete Fail");
            Assert.AreEqual(newOrderIndex, (OldOrderIndex - 1), "Delete Fail");
        }

        [Test]
        public void UpdateTest()
        {
            var obj = _labelService.GetAll().FirstOrDefault();

            var newIcon = "Test New Icon";
            obj.Icon = newIcon;

            _labelService.Update(obj);

            var obj2 = _labelService.Get(obj.ID);
            Assert.AreEqual(newIcon, obj2.Icon, "Update Fail");
        }

        //[Test]
        //public void InsertOfParent()
        //{
        //    int maxOrderIndex = _labelService.GetAll().Where(t => t.Parent == null).Max(o => o.OrderIndex);
        //    if (maxOrderIndex > 0)
        //    {
        //        maxOrderIndex += 1;
        //    }
        //    else
        //    {
        //        maxOrderIndex = 0;
        //    }

        //    var todoLable = new TodoLabel
        //    {
        //        Name = "Todo_Test_Parent",
        //        Icon = "123",
        //        OrderIndex = maxOrderIndex
        //    };
        //    int oldCount = _labelService.GetAll().Count + 1;

        //    _labelService.Insert(todoLable);

        //    int newCount = _labelService.GetAll().Count;

        //    Assert.AreEqual(newCount, oldCount, "Insert Fail");
        //}

        //[Test]
        //public void AddOfChild()
        //{
        //    var parent = _labelService.GetAll().FirstOrDefault();

        //    int maxOrderIndex = 0;
        //    int oldSubCount = parent.SubLabels.Count;
        //    if (oldSubCount > 0)
        //    {
        //        maxOrderIndex = parent.SubLabels.Max(o => o.OrderIndex) + 1;
        //    }

        //    var todoChild = new TodoLabel
        //    {
        //        Name = "Todo_Test_Child",
        //        Parent = parent,
        //        Icon = "",
        //        OrderIndex = maxOrderIndex
        //    };

        //    _labelService.Add(todoChild);

        //    parent.SubLabels.Add(todoChild);

        //    _labelService.Update(parent);

        //    var parent2 = _labelService.Get(parent.ID);
        //    Assert.AreEqual(parent2.SubLabels.Count, (oldSubCount + 1), "The SubLables Insert Fail.");

        //}
    }
}